from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select, WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re, datetime
import sys, argparse, optparse, pyodbc, inspect
import SeleniumTestHelper


##Fix or workaround the Export Errors

class APCFamilyRoomRegressionWD(unittest.TestCase):
    
    @classmethod
    def setUpClass(self):
        name_of_test=(str(inspect.stack()[0][3]))
        self.verificationErrors = []
        self.dirty_data=[]
        self.driver = webdriver.Firefox()
        self.base_url = "http://"
        self.driver.implicitly_wait(15)
        driver = self.driver
        
        # Start Page to Set Variables
        print("running variables test")
        driver.get("http://localhost:8080/sql/familyRoomRegression")
        time.sleep(5)
        #Store HF in selection
        self.hf_in_selection =driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(3) td:nth-child(1)").text
        self.hf_in_selection_LN= driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(3) td:nth-child(3)").text
        self.hf_in_selection2 =driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(4) td:nth-child(1)").text
        self.hf_in_selection_LN2= driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(4) td:nth-child(3)").text
        self.hf_in_selection3 =driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(5) td:nth-child(1)").text
        self.hf_in_selection_LN3= driver.find_element_by_css_selector("table[id='hf_selection_approved'] tbody tr:nth-child(5) td:nth-child(3)").text
        print("hf_in_selection: " + self.hf_in_selection)

        #Store HF renewals
        self.hf_renewing =driver.find_element_by_css_selector("table[id='hf_renewals'] tbody tr:nth-child(3) td:nth-child(1)").text
        print ("hf_renewing: " + self.hf_renewing)
        
        #Store HF Applying
        self.hf_applying = driver.find_element_by_css_selector("table[id='hf_applying'] tbody tr:nth-child(3) td:nth-child(1)").text
        self.hf_applying2 = driver.find_element_by_css_selector("table[id='hf_applying'] tbody tr:nth-child(4) td:nth-child(1)").text
        self.hf_applying3 = driver.find_element_by_css_selector("table[id='hf_applying'] tbody tr:nth-child(5) td:nth-child(1)").text
        print ("hf_applying: " +self.hf_applying)
        
        time.sleep(3)
        driver.quit()
        
    def setUp(self):
        name_of_test=(str(inspect.stack()[0][3]))
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(15)
        now = datetime.datetime.now()
        print ("time is:  ",now.strftime("%Y-%m-%d %H:%M:%S"))
        
        
        
    
    def test_fr_b_in_selection(self):
        name_of_test=(str(inspect.stack()[0][3]))
        print("\n running hf_in selection")
        driver = self.driver
        hf_in_selection =self.hf_in_selection 
        hf_in_selection_LN=self.hf_in_selection_LN
        hf_in_selection2 = self.hf_in_selection2 
        hf_in_selection_LN2=self.hf_in_selection_LN2
        hf_in_selection3= self.hf_in_selection3 
        hf_in_selection_LN3=self.hf_in_selection_LN3
        # ERROR: Caught exception [ERROR: Unsupported command [setSpeed | 300 | ]]
        print("Test running in the " + ENVIRONMENT)
       

        
       
        try:
            # **Family Room Tests
            # *In Selection HF
            
            driver.get(self.base_url + FAMILYROOM + "/fr/home.cfm")
            
            driver.find_element_by_id("login_user").clear()
            driver.find_element_by_id("login_user").send_keys(hf_in_selection)
            driver.find_element_by_id("login_password").clear()
            driver.find_element_by_id("login_password").send_keys("changeme")
            driver.find_element_by_id("login_submit").click()
            
            # Deal with Interview Feedback Screen
            for i in range (0,3):
                try:self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"Our records indicate that you requested an interview")
                except AssertionError:
                    Select(driver.find_element_by_css_selector("select[name=\"feedback_reason\"]")).select_by_visible_text("Au pair has declined my match offer")
                    SeleniumTestHelper.SeleniumTestHelper.find_element_by_sizzle("tr:contains('I will not match') input").click()
                    driver.find_element_by_css_selector("input[name=\"submitPopUpFeedback\"]").click()
            
            # *Deal with Au Pair Search is Unavailable
            time.sleep(3)
            driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            try:self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"Viewing Au Pairs Is Not Available")
            except AssertionError:
                print ("HF Con't view AP's. Logging in as next as next HF")
                self.dirty_data.append(hf_in_selection)
                hf_in_selection= hf_in_selection2
                hf_in_selection_LN= hf_in_selection_LN2
                # If true then set login info to next HF and login as them
                driver.find_element_by_css_selector("#logout").click()
                print(hf_in_selection)
                driver.get(self.base_url + FAMILYROOM + "/fr/home.cfm")
                driver.find_element_by_id("login_user").clear()
                driver.find_element_by_id("login_user").send_keys(hf_in_selection)
                driver.find_element_by_id("login_password").clear()
                driver.find_element_by_id("login_password").send_keys("changeme")
                driver.find_element_by_id("login_submit").click()
            # Fr: Go to HF Profile page and verify HF's email address is accurate
            driver.get(self.base_url + FAMILYROOM + "/fr/profile.cfm")
            # Warning: verifyTextPresent may require manual changes
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, hf_in_selection)
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Fr: Find AP's
            driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            #Confirm number of AP results >0
            records_found = driver.find_element_by_css_selector("form[name=\"form2\"] + strong").text
            records_found_reg = re.search(r'(\d+$)', records_found)
            try: self.assertGreater(int(records_found_reg.group(0)), 0, "AP results not found for hf_inselection .. uh oh!!") 
            except AssertionError as e: self.verificationErrors.append(str(e))    
            #View AP details    
            driver.find_element_by_css_selector("img[alt=\"View Details\"]").click()
            # Remove Ap from Search
            time.sleep(2)
            driver.find_element_by_css_selector("#takeoff").click()
            # Add back AP to search
            time.sleep(2)
            driver.find_element_by_css_selector("#addback").click()
            print("finished adding AP back to search")
            
            # Add AP to Favorites
            # TO DO: FInd button Remove from Faves. 
            in_favorites = self.is_element_present(By.CSS_SELECTOR, "td a img[src$=\"images/btn_favorite_bl.gif\"]")
            print("Is AP in favorites already?" , in_favorites)
            ##Stopped here
            if in_favorites==0:
                driver.find_element_by_css_selector("#add").click()
                time.sleep(1)
            AP_name = driver.find_element_by_css_selector("td.name_barListing").text
            time.sleep(2)
            print("AP for favorites testcase: ",AP_name)
            # Favorites Page
            driver.get(self.base_url + FAMILYROOM + "/fr/favorites.cfm?type=favorites")
            print("Opening Favorites page, where our AP should be listed")
            time.sleep(3)
            # Warning: verifyTextPresent may require manual changes
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, AP_name)
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Remove From Favorites
            driver.find_element_by_css_selector("#remove").click()
            print("removed our AP from faves")
            time.sleep(2)
            # Warning: verifyTextNotPresent may require manual changes
            try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, AP_name)
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Search for AP's
            print ("searching AP's for interview")
            driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            driver.find_element_by_css_selector("input#location_OutOfCountry").click()
            Select(driver.find_element_by_css_selector("select[name=\"gender\"]")).select_by_visible_text("Female")
            driver.find_element_by_css_selector("[name=submitSearch]").click()
            # Attempt to Interview AP
            print ("Attempting to Interview AP")
            driver.find_element_by_css_selector("img[alt=\"View Details\"]").click()
            
            
            
            
            driver.find_element_by_css_selector("img[alt=\"Interview This Au Pair\"]").click()
            driver.find_element_by_css_selector("input[name=\"submit\"]").click()
            try: self.assertEqual("Your Au Pair Is Ready To Be Interviewed", driver.find_element_by_css_selector("h5.sysmessage").text)
            except AssertionError as e: self.verificationErrors.append(str(e))
            #Verify text "Time Zone"
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Time Zone[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Verify email address is there
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*@[\s\S]*\.[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Cancel Interview
            print("Cancel interview testcase")
            driver.find_element_by_css_selector("[alt=\"Cancel Interview\"]").click()
            driver.find_element_by_css_selector("#interview1000317").click()
            Select(driver.find_element_by_css_selector("select[name=\"feedback_reason\"]")).select_by_visible_text("Au pair has declined my match offer")
            driver.find_element_by_css_selector("textarea[name=\"HFfeedbackmsg\"]").clear()
            driver.find_element_by_css_selector("textarea[name=\"HFfeedbackmsg\"]").send_keys("Declined!")
            driver.find_element_by_css_selector("input[name=\"submitFeedback\"]").click()
            
            # Confirm Interview AP
            driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            # Select Out of Country and non-Infant Specialized
            Select(driver.find_element_by_css_selector("select[name=\"gender\"]")).select_by_visible_text("Female")
            driver.find_element_by_css_selector("input#location_OutOfCountry").click()
            driver.find_element_by_css_selector("input[type=\"radio\"][value=\"2\"][name=\"Cinfantspecialized\"]").click()
            driver.find_element_by_css_selector("[name=submitSearch]").click()
            driver.find_element_by_css_selector("img[alt=\"View Details\"]").click()
            driver.find_element_by_css_selector("img[alt=\"Interview This Au Pair\"]").click()
            driver.find_element_by_css_selector("input[name=\"submit\"]").click()
            try: self.assertEqual("Your Au Pair Is Ready To Be Interviewed", driver.find_element_by_css_selector("h5.sysmessage").text)
            except AssertionError as e: self.verificationErrors.append(str(e))
            # Warning: verifyTextNotPresent may require manual changes
            try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            time.sleep(4)
            # Finalize Match
            driver.find_element_by_css_selector("img[alt=\"Finalize This Match\"]").click()
     
            #Replacement Au Pair testcase
            try:self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"replacement au pair ")
            except AssertionError:
                
                Select(driver.find_element_by_css_selector("[name=\"ArrivalDate\"]")).select_by_index("1")
                Select(driver.find_element_by_css_selector("select[name=\"NearestAirportId\"]")).select_by_index("9")
                driver.find_element_by_css_selector("input[name=\"terms4\"]").click()
                driver.find_element_by_css_selector("input[name=\"terms5\"]").click()
                driver.find_element_by_css_selector("input[name=\"terms6\"]").click()
                time.sleep(3)
                driver.find_element_by_css_selector("input[name=\"confirmMatch\"]").click()
                # Warning: assertTextNotPresent may require manual changes
                self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*You are about to request a match with[\s\S]*$")
                # Warning: verifyTextNotPresent may require manual changes
                try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred[\s\S]*$")
                except AssertionError as e: self.verificationErrors.append(str(e))
                
            if (self.is_element_present(By.CSS_SELECTOR, "input[name=\"EnrollInfantSpecialized\"]")) ==1:
                #Select regular, non-IS AP
                SeleniumTestHelper.SeleniumTestHelper.find_element_by_sizzle("input[type=\"radio\"][value=0][name=\"EnrollInfantSpecialized\"]").click()
                # Select Arrival Date/Airport from Drop Down
                Select(driver.find_element_by_css_selector("[name=\"ArrivalDate\"]")).select_by_index("1")
                Select(driver.find_element_by_css_selector("select[name=\"NearestAirportId\"]")).select_by_index("9")
                driver.find_element_by_css_selector("input[name=\"paymentoptionid\"][value=\"0\"]").click()
                # Payment by Check
                driver.find_element_by_xpath("(//input[@name='paymentMethod'])[2]").click()
                driver.find_element_by_css_selector("input[name=\"terms4\"]").click()
                driver.find_element_by_css_selector("input[name=\"terms5\"]").click()
                driver.find_element_by_css_selector("input[name=\"terms6\"]").click()
                time.sleep(3)
                driver.find_element_by_css_selector("input[name=\"confirmMatch\"]").click()
                
                self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*You are about to request a match with[\s\S]*$")
        
                try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*You have requested a match with[\s\S]*$")
                except AssertionError as e: self.verificationErrors.append(str(e))
            
                # TO DO: Add CC payment
            
            
            
            
            # *Finalize in Casper
            driver.get(self.base_url + CASPER +"/index.cfm")
            try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred While Processing Request[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            try:self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"Logged in:")
            except AssertionError:
                print ("Loggin in to Casper")
                driver.find_element_by_name("username").clear()
                driver.find_element_by_name("username").send_keys(CASPER_login)
                driver.find_element_by_name("password").clear()
                driver.find_element_by_name("password").send_keys("changeme")
                driver.find_element_by_css_selector("input[type=\"submit\"]").click()
                try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred[\s\S]*$")
                except AssertionError as e: self.verificationErrors.append(str(e))
            
    #        # Casper: FR Match List
            driver.get(self.base_url + CASPER +"/apc/ListFRMatches.cfm?type=requested")
            print("HF in_selection Last Name we are working with: ",hf_in_selection_LN)
    #        # Finalize Placement in Casper
            try: SeleniumTestHelper.SeleniumTestHelper.find_element_by_sizzle("tr:contains(" + hf_in_selection_LN + ") a:contains('Finalize!')").click()
            except IndexError as e : self.verificationErrors.append(str(e))
            Select(driver.find_element_by_css_selector("select[name=\"ArrivalDate\"]")).select_by_index("7")
            driver.find_element_by_css_selector("input[type=\"submit\"][value=\"Finalize Placement\"]").click()
            try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred While Processing Request[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            
            
            # Account Tab
            driver.get(self.base_url + CASPER +"/apc/ListHostFamilyInvoices.cfm")
            SeleniumTestHelper.SeleniumTestHelper.find_element_by_sizzle("a:contains(" + hf_in_selection_LN + ")").click()
    
            # Warning: verifyTextPresent may require manual changes
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]* SEVIS FEE [\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e)[:80])
            # Warning: verifyTextPresent may require manual changes
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Boston Domestic Surcharge[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e)[:80])
            print ("Finished Hf_in_selection \n")
        
        except Exception as e:
            SeleniumTestHelper.SeleniumTestHelper.exception_found(e, driver)
            self.verificationErrors.append(str(e))
            
#            source = str(driver.page_source())
#            print(source)
#not working, need example.
#    source = str(driver.page_source())
#TypeError: 'unicode' object is not callable
    
    
    def test_fr_c_renewal(self):
        name_of_test=(str(inspect.stack()[0][3]))
        print("\n running hf_renewal")
        #Renewing HF
        driver = self.driver
        hf_renewing= self.hf_renewing
        driver.get(self.base_url + FAMILYROOM + "/fr/home.cfm")
        driver.find_element_by_id("login_user").clear()
        driver.find_element_by_id("login_user").send_keys(hf_renewing)
        driver.find_element_by_id("login_password").clear()
        driver.find_element_by_id("login_password").send_keys("changeme")
        driver.find_element_by_id("login_submit").click()
        print("Hf_renewal: ", hf_renewing)
        # verify Renew App link is present
        try: self.assertTrue(self.is_element_present(By.CSS_SELECTOR, "li[id=\"renewApp\"]"))
        except AssertionError as e: self.verificationErrors.append(str(e))
        driver.get(self.base_url + FAMILYROOM + "/fr/my_aupairs.cfm")
        # Warning: verifyTextNotPresent may require manual changes
        try: self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Error Occurred[\s\S]*$")
        except AssertionError as e: self.verificationErrors.append(str(e))
        
        #Test failure
#        try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]* SEVIS F!!!!!EE [\s\S]*$", "Yikes!! %s" % str(inspect.stack()[0][3]))
#        except AssertionError as e: self.verificationErrors.append(str(e)[:80])
       
        
    def test_fr_d_applying(self):
        name_of_test=(str(inspect.stack()[0][3]))
        self.driver.implicitly_wait(30)
        
        try:
            print("running hf_applying")
            # **Applying HF
            driver = self.driver
            hf_applying= self.hf_applying
            hf_applying2= self.hf_applying2
            hf_applying3= self.hf_applying3
            
            driver.get(self.base_url + FAMILYROOM + "/fr/home.cfm")
            
            #driver.find_element_by_id("This will FAIL!!").clear()
            
            
            driver.find_element_by_id("login_user").clear()
            driver.find_element_by_id("login_user").send_keys(hf_applying)
            print("Testing with HF_applying: ", hf_applying)
            driver.find_element_by_id("login_password").clear()
            driver.find_element_by_id("login_password").send_keys("changeme")
            driver.find_element_by_id("login_submit").click()
           
            # *Deal with Au Pair Search is Unavailable
            time.sleep(3)
            driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            try:self.assertNotRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"Viewing Au Pairs Is Not Available")
            except AssertionError:
                print ("HF Con't view AP's. Logging in as next as next HF")
                self.dirty_data.append(hf_applying)
                hf_applying= hf_applying2
                # If true then set login info to next HF and login as them
                driver.find_element_by_css_selector("#logout").click()
                print(hf_applying)
                driver.get(self.base_url + FAMILYROOM + "/fr/home.cfm")
                driver.find_element_by_id("login_user").clear()
                driver.find_element_by_id("login_user").send_keys(hf_applying)
                driver.find_element_by_id("login_password").clear()
                driver.find_element_by_id("login_password").send_keys("changeme")
                driver.find_element_by_id("login_submit").click()
                driver.get(self.base_url + FAMILYROOM + "/fr/advanced_search2.cfm?featured")
            
            
            driver.find_element_by_css_selector("img[alt=\"View Details\"]").click()
            time.sleep(2)
            driver.find_element_by_css_selector("img[alt=\"Interview This Au Pair\"]").click()
            driver.find_element_by_css_selector("input[name=\"submit\"]").click()
            driver.find_element_by_css_selector("img[alt=\"Finalize This Match\"]").click()
            time.sleep(2)
            
            try: self.assertTrue(self.is_element_present(By.CSS_SELECTOR, "input[type=\"submit\"][value=\"Request Courtesy Hold\"]"))
            except AssertionError as e: self.verificationErrors.append(str(e))
            driver.find_element_by_css_selector("input[type=\"submit\"][value=\"Request Courtesy Hold\"]").click()
            time.sleep(4)
            try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Courtesy Hold Confirmed[\s\S]*$")
            except AssertionError as e: self.verificationErrors.append(str(e))
            
            print ("finished with %s" % str(inspect.stack()[0][3]))
            
        except Exception as e:
            SeleniumTestHelper.SeleniumTestHelper.exception_found(e, name_of_test, driver)

            self.verificationErrors.append(str(e))
            
            
                
    def ztest_print(self):
        print("running test_print")
        driver = self.driver
        
        
        try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]* SEVIS F!!!!!EE [\s\S]*$", "%s: Failure" % str(inspect.stack()[0][3]))
        except AssertionError as e: self.verificationErrors.append ((e))
        # Warning: verifyTextPresent may require manual changes
        
        try: self.assertRegexpMatches(driver.find_element_by_css_selector("BODY").text, r"^[\s\S]*Boston D!!!!!omestic Surcharge[\s\S]*$","%s: Failure" % str(inspect.stack()[0][3]))
        except AssertionError as e: self.verificationErrors.append(str(e))
    
    
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True
    
    def tearDown(self):
        time.sleep(5)
        self.driver.quit()
        
        
    @classmethod
    def tearDownClass(self):
        
        print ("This data needs investigation/cleanup: ",self.dirty_data)
        #self.assertEqual([], self.verificationErrors)
        print ("Total Failed: "+str(len(self.verificationErrors)),self.verificationErrors)
        print("Inspect Stack function: ",(inspect.stack()[0][3]))

if __name__ == '__main__':    
    #add you app's options here...
    options_tpl = ('dev', 'qa', 'stage', 'prod' ) #, '--in_dir', '-o', '--out_dir')
    del_lst = []
    #Edit: changed i to e to prevent i being used twice... so far not an issue
    for e,option in enumerate(sys.argv):
        if option in options_tpl:
            print("passing in environment: " +option)
            #if option in options_tpl:
            if option == 'dev':
                print "running tests for: DEV"
                from VariablesDEV_WD import *
                SeleniumTestHelper.SeleniumTestHelper.our_db_setter("JV_DEV")
                            
            elif option == "qa":
                print "running tests for: QA"
                from VariablesQA_WD import *
                SeleniumTestHelper.SeleniumTestHelper.our_db_setter("JV_QA")
                
            elif option == "stage":
                print "running tests for: STAGE"
                from VariablesSTAGE_WD import * 
                SeleniumTestHelper.SeleniumTestHelper.our_db_setter("JV_STAGE")
                
            elif option == "prod":
                print "You are running the test in Prod. This is not allowed"    
                
            
            del_lst.append(e)
    
    #used to remove one of the argv options to prevent it from interfering with unittest.        
    del_lst.reverse()
    for i in del_lst:
        optparse 
        del sys.argv[i]
        
    unittest.main()
